package Compilador;

import java.util.jar.Manifest;
import java.util.jar.Attributes;
import java.util.LinkedList;
import java.util.List;
import java.util.Iterator;
import java.io.*;

/**
 *  */
/**
 * Escribe los objetos manifiestos. Útil para crear archivos de manifiesto sin
 * escribir en archivos.
 *
 * 
 *
 */
public class EscritorManifest {

    private List<String> _classPaths;
    private String _mainClass;
    private String _rawManifest;
    public static final Manifest DEFAULT = new EscritorManifest().getManifest();

    public EscritorManifest() {
        _classPaths = new LinkedList<String>();
        _mainClass = null;
        _rawManifest = null;
    }

    /*
     * Agrega una la ruta de una clase al manifest
     *
     * 
     * @param path ruta de la clase
     * @return void
     */
    public void addClassPath(String path) {
        _classPaths.add(_classPaths.size(), path);
    }

    /**
     * Establece la clase main
     *  
     * @param mainClass clase main
     */
    public void setMainClass(String mainClass) {
        _mainClass = mainClass;
        _rawManifest = null;
    }

    public void setManifestContents(String rawManifest) {
        _rawManifest = rawManifest;
        _mainClass = null;
    }

    /**
     * devuelve el manifiest
     *
     * @return  InputStream 
     * 
     */
    protected InputStream getInputStream() {
    

        final StringBuilder sbuf = new StringBuilder();
        sbuf.append(Attributes.Name.MANIFEST_VERSION.toString());
        sbuf.append(": 1.0" + "\n");
        if (!_classPaths.isEmpty()) {
            Iterator<String> iter = _classPaths.iterator();
            sbuf.append(Attributes.Name.CLASS_PATH.toString());
            sbuf.append(":");
            while (iter.hasNext()) {
                sbuf.append(" ");
                sbuf.append(iter.next());
            }
            sbuf.append("\n");
        }
        if (_mainClass != null) {
            sbuf.append(Attributes.Name.MAIN_CLASS.toString());
            sbuf.append(": ");
            sbuf.append(_mainClass);
            sbuf.append("\n");
        }

        if (_rawManifest != null) {
            sbuf.append(_rawManifest);

            if (!_rawManifest.endsWith("\n")) {
                sbuf.append("\n");
            }
        }

        try {
            return new ByteArrayInputStream(sbuf.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * obtener el objeto manifest creado
     *
     * @return manifest
     */
    public Manifest getManifest() {
        try {
            Manifest m = new Manifest();
            m.read(getInputStream());
            return m;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}